home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d27
/
rpgf_pc2.exe
/
RFREE.DOC
< prev
next >
Wrap
Text File
|
1991-02-28
|
83KB
|
2,396 lines
-----------------------------------------------------------------------------
RFREE.DOC -- RPG/free (tm) and RPG/pretty (tm) documentation
-----------------------------------------------------------------------------
Version PC2.02 February 28, 1991
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
by Paul Conte (Copyright 1990, 1991)
Please note: This document can be reproduced for any purpose, as long as
the following notice is included on the first page:
***************************************************************************
*** RPG/free and RPG/pretty are trademarks of Paul Conte. ***
*** ***
*** RPG/free and RPG/pretty programs are ***
*** Software copyright 1990, 1991 by Paul Conte. *** ***
***************************************************************************
TABLE OF CONTENTS
-----------------
I. . . . . . . . . . . . . . . . . How to use this document
II. . . . . . . . . . . . . . . . . Introduction
III. . . . . . . . . . . . . . . . Installation
IV. . . . . . . . . . . . . . . . . Execution
IV.A. . . . . . . . . . . . . . . . DOS commands
IV.B. . . . . . . . . . . . . . . . Error files
IV.C. . . . . . . . . . . . . . . . Return status
IV.D. . . . . . . . . . . . . . . . RPG/free options
IV.E. . . . . . . . . . . . . . . . RPG/pretty options
V. . . . . . . . . . . . . . . . . What's new in Versions 2.0 and 2.02
VI. . . . . . . . . . . . . . . . . Compiler notes
VI.A. . . . . . . . . . . . . . . . Opcode and operand formats
VI.B. . . . . . . . . . . . . . . . RPG II
VI.C. . . . . . . . . . . . . . . . RPG III and RPG/400
VI.D. . . . . . . . . . . . . . . . ASNA 400 RPG
VI.E. . . . . . . . . . . . . . . . Lattice RPG II
VI.F. . . . . . . . . . . . . . . . Native Software RPG 400
VI.G. . . . . . . . . . . . . . . . BPS RPG II 1/2
VI.H. . . . . . . . . . . . . . . . Other vendor extensions
VII. . . . . . . . . . . . . . . . RPG/free translation notes
VIII. . . . . . . . . . . . . . . . RPG/pretty translation notes
VIII.A. . . . . . . . . . . . . . . Handling of S/38 and AS/400 SRCDAT
and SRCSEQ fields
VIII.B. . . . . . . . . . . . . . . Tab conversion
VIII.C. . . . . . . . . . . . . . . Program ID
VIII.D. . . . . . . . . . . . . . . Comments
VIII.E. . . . . . . . . . . . . . . Miscellaneous
IX. . . . . . . . . . . . . . . . . Reverse translation
X. . . . . . . . . . . . . . . . . Implementation notes
X.A. . . . . . . . . . . . . . . . Maxima
XI. . . . . . . . . . . . . . . . . The RPG/free language
XI.A. . . . . . . . . . . . . . . . Statements
XI.B. . . . . . . . . . . . . . . . Comments
XI.C. . . . . . . . . . . . . . . . Continuation
XI.D. . . . . . . . . . . . . . . . Program structure
XI.E. . . . . . . . . . . . . . . . Non-C-spec statements
XI.F. . . . . . . . . . . . . . . . C-spec statements
XI.G. . . . . . . . . . . . . . . . Multiple C-spec statements
XI.H. . . . . . . . . . . . . . . . Sequence field (1-5)
XI.I. . . . . . . . . . . . . . . . Control level indicator (7-8)
XI.J. . . . . . . . . . . . . . . . Conditioning indicators (7-8 and 9-17)
XI.K. . . . . . . . . . . . . . . . Operation (18-48)
XI.L. . . . . . . . . . . . . . . . RPG/free operations
XI.M. . . . . . . . . . . . . . . . Arithmetic assignments
XI.N. . . . . . . . . . . . . . . . Keyword operations
XI.O. . . . . . . . . . . . . . . . Opcode synonyms
XI.P. . . . . . . . . . . . . . . . Operand keywords
XI.Q. . . . . . . . . . . . . . . . Extended control structure operations
XI.R. . . . . . . . . . . . . . . . Extended character assignment
operations
XI.S. . . . . . . . . . . . . . . . Declarations (49-52)
XI.T. . . . . . . . . . . . . . . . DCL operation
XI.U. . . . . . . . . . . . . . . . Half-adjust (53)
XI.V. . . . . . . . . . . . . . . . Resulting indicators (54-59)
XII. . . . . . . . . . . . . . . . Standard RPG directives
XIII. . . . . . . . . . . . . . . . RPG/free directives
XIII.A. . . . . . . . . . . . . . . Setting the first column (/FIRSTCOL)
XIII.B. . . . . . . . . . . . . . . Source macros (/DEFINE, /UNDEFINE,
and /DUMPMAC)
XIII.C. . . . . . . . . . . . . . . Predefined language, compiler, and
logical constant macros
XIII.D. . . . . . . . . . . . . . . DOS command line macro definition
(/define:xxx option)
XIII.E. . . . . . . . . . . . . . . Conditional code generation
(/IF, /ELSEIF, /ELSE, and /ENDIF)
XIII.F. . . . . . . . . . . . . . . Fixed format input (/FIX and /FREE)
XIII.G. . . . . . . . . . . . . . . Including source files
(/INCLUDE and /INCLUDEF)
XIII.H. . . . . . . . . . . . . . . Combining macros and include files
XIV. . . . . . . . . . . . . . . . The Future of RPG/free
I. HOW TO USE THIS DOCUMENT
---------------------------
This document is an ASCII text file with <CR> at the end of each line.
Tab stops are the DOS defaults (9, 17, ...). Because there are so many
variations in printer setups, this file contains no line or page spacing
other then tabs and blank lines. If you want a "pretty" copy of the
document, import it into your favorite word processor before printing.
II. INTRODUCTION
----------------
RPG/free is a free format version of RPG. The RPG/free precompiler
translates RPG/free input into standard RPG, which can be compiled by one of
the RPG compilers. The RPG/pretty translator translates standard RPG input
into "pretty" RPG/free code. Both RPG/free and RPG/pretty run under MS-DOS
or the DOS compatability box of OS/2. There are also versions of
RPG/free and RPG/pretty that execute on the AS/400 and S/36.
The executable versions of RPG/free and RPG/pretty covered by this
documentation can be freely copied and distributed. They are commercial
quality programs intended for production use; however, because they are free,
no warranty or support is offered. Please use normal care in backing up
files as you use these programs.
If you find errors or have suggestions for improvements, please share
your knowledge. By filling out the form in file FREENEWS, you can receive a
free RPG/free newsletter that contains tips-and-techniques and error reports.
The newsletter also contains the latest information on new releases
of RPG/free and RPG/pretty. The latest releases of the programs are available
on the NEWSLINK bulletin board of NEWS 3X/400 magazine; for information on
NEWSLINK, call 800-373-3853. (Other bulletin boards are free to copy the
latest releases from NEWSLINK to their own system for distribution. My only
request of BBS operators is that you also provide the latest version of this
RFREE.DOC file along with the programs.)
III. INSTALLATION
-----------------
To install from diskette, just copy RF.EXE (for RPG/free) and RP.EXE
(for RPG/pretty) to your PC hard disk. (After you copy the two progams to
your hard disk, you may want to rename the programs to avoid accidentally
typing "RP" instead of "RF" when you execute them. For example, you might
rename RF.EXE to RFREE.EXE.)
You can test the programs by executing:
rf /listopt tstin1.rpf tstin2.rpf out.rpg
rp /listopt tstin.rpg out.rpf
Then compare the generated file OUT.RPG with the supplied file
TSTOUT.RPG, and compare the generated file OUT.RPF with the supplied file
TSTOUT.RPF. These aren't comprehensive tests, but they will at least let you
know you have functioning versions of the programs.
To de-install, just delete any files you no longer want to use.
IV. EXECUTION
-------------
IV.A. DOS COMMANDS:
RPG/free
Memory requirements: Approximately 250K.
Throughput: Approximately 1500 input lines per minute on an
IBM PS/2 Model 55SX (16Mhz) with 60Mb hard disk.
Command:
rf [options] input-file1 input-file2 ... input-filen output-file
RPG/pretty
Memory requirements: Approximately 250K.
Throughput: Approximately 300 input lines per minute on an
IBM PS/2 Model 55SX (16Mhz) with 60Mb hard disk.
Command:
rp [options] input-file output-file
For both programs:
[options] is a list of options, each beginning with a slash (/).
(e.g., /cmtline:same)
At least one input file and one output file are required, the last
file listed is the output file. RPG/pretty can have up to 20 input
files (or your current DOS maximum open file limit).
*** Be sure to include your output file when you use more than one
*** RPG/free input file. The command: rf inp1.rpf inp2.rpf
*** treats inp2.rpf as the output file and replaces its contents.
Use standard DOS file specifications for the input and output files.
You must include the extension when you specify a file.
Recommended file extensions are:
.RPG for standard RPG files
.RPF for RPG/free files
.RPI for included source files (other than macros)
.RPM for included macro files (discussed below)
IV.B. ERROR FILES:
Both programs write information, warning, and error messages to STDOUT.
You can use DOS output redirection to write messages to a disk file. For
example:
rf inp.rpf out.rpg > rf.err
will write all messages to rf.file.
Translation warning and error messages have the same format as
Microsoft C compiler errors:
filespec (111): Warning 222: Message
filespec (111): Error 222: Message
where: 111 is the input line number within filespec,
222 is the message identifier
Many PC programming editors will automatically display warning
and error messages and position you to the source record that caused the
error.
IV.C. RETURN STATUS:
RPG/free and RPG/pretty return a DOS status value:
-1 Command error or internal error
0 No error
10 Exit because /help option entered on command line
20 Translation warning
30 Translation error
You can test the return status with IF ERRORLEVEL in DOS batch files.
IV.D. RPG/free OPTIONS:
-- Execution options:
/help List option switches.
/listopt List the option settings for current execution.
Default is to not list option settings.
/errline Output source line after error messages.
Default is to not output source line after error messages.
-- Formatting and translation options:
/cmtline:xxx Output RPG/free comments (beginning with --) on previous
or same line, where xxx is:
none - Don't output comments
prv - Output comments before statement
same - Output comments at end of statement
Default is /cmtline:prv.
/commadec Decimal point is ',' instead of '.'
Default is '.' for decimal point.
/define:xxxxx Define XXXXX as macro with value '@XXXX'.
/nocvttab Do not convert tabs in input to spaces.
Default is to convert tabs using tab stops [9, 17, ...]
/numbers Output RPG source line numbers in positions 1-5.
Default is to output blanks in 1-5.
/pgmid:xxxxxx Output xxxxxx in program ID field (75-80).
/pgmid:*BLANK Output blanks in program ID.
Default is no program ID (75-80 may be used for comment text).
-- Source compiler options; use no more than one:
Default is /rpgiii.
/asna Output is Amalgamated Software of North America 400 RPG.
/bps Output is BPS Information Services RPG II 1/2.
/cspi Output is California Software Products Inc. RPG II.
/cspi400 Output is California Software Products Inc. RPG 400.
/lattice Output is Lattice, Inc. RPG II.
/native Output is Native Software RPG 400.
/rpgii Output is IBM RPG II (or 100% compatible).
/rpgiii Output is IBM RPG III (or 100% compatible).
/rpg400 Output is IBM RPG/400 (or 100% compatible).
/softwest Output is Software West RPG II.
/trident Output is Trident Software, Inc. RPG III.
IV.E. RPG/pretty OPTIONS:
-- Execution options:
/help List option switches.
/listopt List the option settings for current execution.
/errline Output source line after error messages.
Default is to not output source line after error messages.
-- Formatting and translation options:
/cmtline:xxx Output C-spec comment field (beginning in position 60) on
previous or same line, where xxx is:
none - Don't output comments
prv - Output comment before statement
same - Output comment at end of statement
Default is /cmtline:same.
/cvttab Convert tabs in input to spaces using tab stops [9, 17, ...].
Default is to not convert tabs in input.
/idcap Output identifiers with initial letter in upper case and other
letters in lower case.
/idupper Output identifiers in upper case.
Default is lower case.
/ignpid Do not output the program ID (positions 75-80) as comment.
Default is to output non-blank contents of 75-80 as comment.
/ignmsglines Do not output lines with embedded compiler messages.
Default is to output message lines.
/indent:Nb Use N blanks for each indent.
/indent:Nt Use N tabs for each indent.
Default is 1 tab.
/kwdlower Output keywords in lower case.
Default is upper case.
/maxindent:N Maximum indent is N levels.
Default is 5.
/nbr:xxx Output statement numbers (positions 1-5), where xxx is:
all - Output all statement numbers
ignore - Don't output any statement numbers,
no warning
nonblank - Output nonblank statement numbers
warn - Don't output any statement numbers,
give warning
Default is /nbr:warn
/nodir Do not reverse translate commented RPG/free directives.
Default is to reverse translate commented RPG/free form-type
directives, /FIRSTCOL, /FIX, and /FREE.
/noform Begin H, F, E, I, T, L, O, and U spec output in position 7.
You cannot use /noform and /nbr:all together.
Default is position 6 (form type character).
/sep:Nb Use N blanks between operands.
/sep:Nt Use N tabs between operands.
Default is 1 tab.
/symind Output indicators in symbolic form (*INxx).
Default is nonsymbolic form (xx).
/trimcmt Trim leading blanks from comments.
Default is to leave leading blanks in comments.
-- Source compiler options; use no more than one:
Default is /rpgiii.
/asna Input is Amalgamated Software of North America 400 RPG.
/bps Input is BPS Information Services RPG II 1/2.
/cspi Input is California Software Products Inc. RPG II.
/cspi400 Input is California Software Products Inc. RPG 400.
/lattice Input is Lattice, Inc. RPG II.
/native Input is Native Software RPG 400.
/rpgii Input is IBM RPG II (or 100% compatible).
/rpgiii Input is IBM RPG III (or 100% compatible).
/rpg400 Input is IBM RPG/400 (or 100% compatible).
/softwest Input is Software West RPG II.
/trident Input is Trident Software, Inc. RPG III.
V. WHAT'S NEW IN VERSION 2.0, 2.01, and 2.02
--------------------------------------------
Version 2.0 was initially released as a Beta version. Version 2.02
is the current distribution version. Version 2.0-Beta and 2.02
have the following changes from the previous release (V1.0).
-- Input and output line size increased to 250 characters.
-- Formatting
A number of changes were made to enhance "reverse" translation.
RPG/pretty supports "reverse" translation of RPG/free form type
directives, and /FIX, /FREE, /INCLUDE, and /INCLUDEF.
RPG/free generates /ENDINCLUDE and /ENDINCLUDEF to mark end of
included code.
RPG/pretty /ignpgmid option and RPG/free /pgmid:xxx option, and new
formatting of program ID field.
/cmtline:xxx options and new comment formatting.
Blank lines are formatted differently.
/commadec option to use ',' as decimal point.
-- /AUTORPT form type directive added to support U-specs.
-- Error messages
New message format, similar to Microsoft C compiler errors, for automated
handling by PC editors.
Error messages are written to STDOUT instead of STDERR.
All error messages have a unique number identifying the error.
RPG/free and RPG/pretty return non-zero values if a warning or error
occurs during translation.
/errline option to control printing of source line with error messages.
-- Multiple C-spec operations can be coded on a single input statement.
-- Macros
Replacement text can now be continued across multiple input lines and can
be up to 250 characters (v1.0 limit was 100).
Replacement text can include multiple C-spec operations.
RPG/free comments (beginning with --) can be coded on /DEFINE directive.
/DUMPMAC directive writes current macro table to disk file.
/DEFINE x ... generates error if x is already defined (v1.0 redefined x).
/define:xxx command line option defines XXXX as a macro with
replacement text '@XXX'.
Macros are automatically defined for language version (e.g., ASNA)
and compiler (e.g., RPGIII).
Macro names can begin with underscore (e.g., _mymac).
TO macro is automatically installed with blank replacement text (for
use as "noise" word in operations like MOVE x TO y).
-- Special values
*TRUE generates '1'; *FALSE generates '0'.
-- C-spec sequence field can be coded as: {ABC}
-- LEVEL(*INL0) or LVL(*INL0) can be used for C-spec control indicator.
-- Conditional translation
Conditional directives: /IF [NOT] DEFINED(macro),
/ELSEIF [NOT] DEFINED(macro), /ELSE, and /ENDIF allow conditional
translation of code and data.
-- Non-commented text after RPG/free directives now generates warning.
-- IBM RPG/400
Release 3.0 opcodes supported: CAT, CLEAR, RESET, SCAN, SUBST
String references like X:I supported.
READE and REDPE optional Factor1 supported.
New special values supported: *INZSR, *NOKEY, *PDA
-- ASNA 400 RPG
USE opcode supported.
Factor 1 on EDIT operation can now have form: *11
/PRINT directive supported.
-- Extended assignment operations
XMOVE, XSUBST (RPG/400), XCAT (RPG/400), XCATST (Lattice) operations
clear Result before assignment.
-- Extended control structures
LOOP, BREAK, CONTINUE, EXITSR, and EXITBLOCK operations support new
control structures.
-- New opcode synonyms: BITOFF, ENDLOOP, XCATSTR, XSUBSTR.
-- New resulting indicator keywords for positions 58-59: FND, FOUND
-- New synonyms for F1(), F2(), and R() operand keywords.
For example: READE KEY( custid ) FMT( cusrcd )
-- Dropped or changed options
RPG/pretty
/indentNb is replaced by /indent:Nb
/indentNt is replaced by /indent:Nt
/isn is replaced by /nbr:ignore
/maxindentN is replaced by /maxindent:N
/sepNb is replaced by /sep:Nb
/sepNt is replaced by /sep:Nt
RPG/free
/nocmt is replaced by /cmtline:none
Version 2.01 has the following changes from V2.0-Beta.
-- Formatting
An extra blank line is no longer emitted after opcodes that have
no operands (e.g., RETURN)
C-spec lines that have only a sequence number and a comment now have
the comment formatted like a C-spec line with only a comment.
-- Comments that immediately follow a directive are now handled
properly (e.g., /DATA--Comment ). Previously, the directive
was not recognized unless it was followed by a blank or tab.
-- Macros
A defect in v2.0-Beta truncated without warning macro replacement text
that exceeded the limits. Proper warnings are now generated.
Maximum macro name length is 30 characters (previous versions
allowed 80, the limit was lowered to allow longer replacement text
and more macro definitions).
Maximum macro definitions is now 200 (v2.0-Beta limit was 100).
%SYSSYMBOL built-in macro function is available for automatically
generating standard RPG field names and preventing accidental
duplicate use of RPG field names for different macros.
/DUMPMAC directive writes current macro table to disk file --
The format for each macro is: [macroname] [replacement text] [x]
where x is 'S' for %SYSSYMBOL-defined macros and blank otherwise.
A set of macros for the RPG/free version, the target standard RPG
language, and the target RPG compiler are installed. Several
macros are added that weren't in v2.0-Beta, and the format of the
macro names has been changed to begin and end with underscores.
-- Conditional translation
A defect in the parsing of /IF DEFINED(macro) is fixed. v2.0-Beta
failed unless macro name had surrounding blanks.
-- Extended assignment operations
XSUBST (RPG/400), XCAT (RPG/400), XCATST (Lattice) operations
generate a warning if the Result operand is the same as either
Factor1 or Factor2, because XCAT, XCATST, and XSUBST move
blanks to the REsult before the string operation.
-- Extended control structures
ELSEIF is installed as a macro with "ELSE; IF " as it's
replacement text.
Three "logical operator" special values are installed as built-in
macros that can be used with control structures such as IF:
Special value Replacement text
------------- ----------------
*AND ;AND
*OR ;OR
*NOT IF *TRUE <>
Version 2.02 has the following changes from V2.01.
-- A cosmetic change in an error message in RPG/pretty
VI. COMPILER NOTES
------------------
VI.A. OPCODE AND OPERAND FORMATS:
The following tables shows how RPG/free treats operation arguments:
Logical
Operation Factor1 Factor2 Result Operator Notes
--------- -------- -------- -------- -------- --------------
ACQ Required Required -- --
ADD Optional Required Required --
AND Required Optional -- Optional Extended op
ANDxx Required Required -- --
BEGSR Required -- -- --
BITOF -- Required Required --
BITON -- Required Required --
BREAK -- -- -- -- Extended op
CABxx Required Required Optional --
CALL -- Required Optional --
CAS Optional Optional Required --
CASE Optional Optional Required Optional Extended op
CASxx Optional Optional Required --
CAT Required Required Required -- R3.0 RPG/400
CATST Required Required Required -- Lattice
CHAIN Required Required Optional --
CKDT -- Required Required -- ASNA
CLEAR Optional Required -- --
CLOSE -- Required -- --
COMIT Optional -- -- --
COMP Required Required -- --
CONTINUE -- -- -- -- Extended op
CVDT Required Required Required -- ASNA
DCL -- Optional Required -- Extended op
DEBUG Optional Optional Optional -- RPG III/400
DEBUG Optional Required Optional -- RPG II
DEFN Required Optional Required -- RPG III/400
DEFN Required Required Required -- RPG II
DELET Optional Required -- --
DIV Optional Required Required --
DO Optional Optional Optional --
DOUxx Required Required -- --
DOWxx Required Required -- --
DSPLY Optional Optional Optional --
DUMP Optional -- -- --
EDIT Required Required Required -- ASNA
ELSE -- -- -- --
END -- Optional -- --
ENDSR Optional Optional -- --
ENDSS -- Required Required -- Lattice
EXCPT -- Optional -- --
EXFMT -- Required -- --
EXIT -- Required -- -- RPG II
EXITBLOCK -- -- -- -- Extended op
EXSR -- Required -- --
FEOD -- Required -- --
FOR Required Required Required Required Extended op
FORCE -- Required -- --
FREE -- Required -- --
GOTO -- Required -- --
IF Required Optional -- Optional Extended op
IFxx Required Required -- --
IN Optional Required -- --
KEYxx Optional -- Optional -- RPG II
KFLD -- -- Required --
KLIST Required -- -- --
LOKUP Required Required Optional --
LOOP -- -- -- -- Extended op
MHHZO -- Required Required --
MHLZO -- Required Required --
MLHZO -- Required Required --
MLLZO -- Required Required --
MODE -- Required -- -- Native Software
MOVEx -- Required Required --
MULT Optional Required Required --
MVR -- -- Required --
NEXT Required Required -- --
OCUR Optional Required Optional --
OPEN -- Required -- --
OR Required Optional -- Optional Extended op
ORxx Required Required -- --
OUT Optional Required -- --
PARM Optional Optional Required --
PLIST Required -- -- --
POST Optional Optional Optional -- RPG III/400
POST Required -- Required -- RPG II
RDCOM -- -- Required -- Native Software
READ -- Required Optional --
READC -- Required -- --
READE Optional Required Optional -- R3.0 RPG/400
READE Required Required Optional -- RPG III
READP -- Required Optional --
REDPE Optional Required Optional -- R3.0 RPG/400
REDPE Required Required Optional -- RPG III
REL Required Required -- --
RESET Optional Required -- --
RETRN -- -- -- --
RLABL -- -- Required -- RPG II
ROLBK -- -- -- --
SCAN Required Required Optional --
SETGT Required Required -- --
SETLL Required Required -- --
SETOF -- -- -- --
SETON -- -- -- --
SETxx Optional Optional Optional -- RPG II
SHTDN -- -- -- --
SORTA -- Required -- --
SQRT -- Required Required --
SUB Optional Required Required --
SUBST Required Required Required -- R3.0 RPG/400
SUBST Required Required -- -- Lattice
TAG Required -- -- --
TESTB -- Required Required --
TESTN -- -- Required --
TESTZ -- -- Required --
TIME -- -- Required --
UNLCK -- Required -- --
UNTIL Required Optional -- Optional Extended op
UPDAT -- Required Optional --
USE -- Required -- -- ASNA
WAIT -- Required -- -- ASNA
WHILE Required Optional -- Optional Extended op
WRCOM -- Required -- -- Native Software
WRITE -- Required Optional --
XCAT Required Required Required -- Extended op -
RPG/400
XCATST Required Required Required -- Extended op -
Lattice
XFOOT -- Required Required --
XMOVE -- Required Required -- Extended op
XSUBST Required Required Required -- Extended op -
RPG/400
Z-ADD -- Required Required --
Z-SUB -- Required Required --
VI.B. RPG II:
Most RPG II opcodes are handled fine with the default /rpgiii compiler
type. The following opcodes may require /rpgii or one of the third-party
RPG II compiler options (depending on which operands you use for Factor1,
Factor2, and Result):
DEBUG
DEFN
POST
The /rpgii option is required for the following translations:
-- RPG/pretty
Recognize ** in positions 1-2 with non-blank in 3 as beginning of
data. (Default /rpgiii requires position 3 to be blank.)
Recognize /* in positions 1-2 as end-of-file.
Handle embedded compiler messages that begin with ??x.
VI.C. RPG III and RPG/400:
Release 3.0 of RPG/400 changed Factor1 from a required operand to an
optional operand on READE and REDPE2, so you will need the /rpg400 switch
if you do not use Factor1.
You do not need to use /rpg400 to use the new RPG/400 opcodes such as
CLEAR and SUBST.
VI.D. ASNA 400 RPG:
ASNA Indicator Keywords
Opcode Factor1 Factor2 Result 54-55 56-57 58-59
------ ------- ------- ------ ----- ----- -----
CKDT Blank Rqd Rqd
CVDT Rqd Rqd Rqd
EDIT Rqd Rqd Rqd
USE Blank Rqd Blank
WAIT Blank Rqd Blank
/PRINT GEN Compiler directive
/PRINT NOGEN
The /asna option is required for the following translations:
-- RPG/free
EDIT opcode Factor1 edit code operands like *11.
-- RPG/pretty
Required to handle embedded compiler messages that have an
accent (`) in position 6.
VI.E. LATTICE RPG II:
Vendor RPG/free Indicator Keywords
Opcode Synonym Factor1 Factor2 Result 54-55 56-57 58-59
------ ----------- ------- ------- ------ ----- ----- -----
blank ENDSS or Blank Rqd Rqd
ENDSUBSTR
CATST CATSTR Rqd Rqd Rqd
SUBST SUBSTR Rqd Rqd Blank
MOVE XCATSTR Rqd Rqd Rqd
CATST
Note that XCATSTR generates a MOVE *BLANK and a CATST. Lattice does not
support XSUBSTR because the Lattice version of the substring operation spans
two RPG/free C-spec statements.
The /lattice option is required for the following translations:
-- RPG/free
Hexadecimal constants like X'FFFF....' into X'FFFF....
CATSTR and XCATSTR to Lattice CATST opcode.
ENDSS to blank opcode.
Distinguish Lattice and RPG/400 variations of SUBST opcode.
-- RPG/pretty
Hexadecimal constants like X'FFFF.... into X'FFFF....'
Blank opcode following SUBST to ENDSUBSTR.
Distinguish Lattice and RPG/400 variations of SUBST opcode.
If you use a Lattice "compressed" file as input to RPG/pretty, you
should use the /cvttab option.
VI.F. NATIVE SOFTWARE RPG 400:
Vendor Indicator Keywords
Opcode Factor1 Factor2 Result 54-55 56-57 58-59
------ ------- ------- ------ ----- ----- -----
MODE Blank Rqd Blank RI3
RDCOM Blank Blank Rqd RI1 RI2 RI3
WRCOM Blank Rqd Blank RI2 RI3
VI.G. BPS RPG II 1/2:
BPS RPG II 1/2 is an RPG II precompiler that uses some non-standard
statement formats. RPG/free and RPG/pretty do not support RPG II 1/2
ten-character Result fields; macro definitions; or macro variables. Before
running RPG II 1/2 code through RPG/pretty, you should bracket non-standard
statements with */FIX and */FREE. RPG/pretty will then generate
fixed-format RPG/free source and the appropriate /FIX and /FREE directives.
The /bps option is required for the following translations:
-- RPG/pretty
To recognize *? in positions 1-2 as beginning of data.
VI.H. OTHER VENDOR EXTENSIONS:
If you encounter a vendor extension that is not properly handled by
RPG/free's translation, the ultimate "work-around" is to use a /FIX
directive, followed by the exact format of the standard RPG statement,
followed by a /FREE directive.
VII. RPG/free TRANSLATION NOTES
-------------------------------
RPG/free does not translate non-C-spec input to uppercase. You should
use uppercase wherever standard RPG requires it in non-C-specs.
Tabs are converted to blanks on input using DOS default tabstops
(9, 17, ...). The /nocvttab option eliminates conversion. The only
place where you might encounter problems are in non-C-specs or quoted
literals, if you are using different tab stops than the defaults. Just
replace any problem tabs with appropriate spaces.
Some error messages list the current token as seen by the parser. You
may see the following "strange" symbols:
EOS End of string (the end of the input statement)
U+ Unary plus (as in X = + Y)
U- Unary minus (as in X = - Y)
In some cases, the translator pushes the current token back on the input
stream and re-parses it. This may cause you to see two or more error
messages for the same token (for example when there is an unclosed string in
the input).
VIII. RPG/pretty TRANSLATION NOTES
----------------------------------
VIII.A. HANDLING OF S/38 AND AS/400 SRCDAT AND SRCSEQ FIELDS:
RPG/pretty determines where position 1 of the standard RPG specification
is in the DOS file by examining the first input record to see if there are
S/38 or AS/400 SEU-style source numbers or dates (not the RPG statement
numbers in RPG positions 1-5). These source numbers and dates are normally
stripped when you use PC Support on the S/38 or AS/400 to download a source
file member. But if they are included, RPG/pretty can normally figure out
how to skip them.
If you want to preserve the SRCDAT field for S/38 or AS/400 source
files, you can use two DOS utilities: Date/pretty and Date/free. These
utilities, along with their documentation and source code are available on
the NEWSLINK BBS. They are Awk programs and can only be used with DOS or
OS/2.
The rules RPG/pretty uses are:
IF characters 1-8 contain xxxxx.nn AND
characters 9-15 contain xxxxxxn
The RPG statement starts in 16
ELSE IF characters 1-7 contain xxxxxxn AND
characters 8-15 contain xxxxx.nn
The RPG statement starts in 16
ELSE IF characters 1-8 contain xxxxx.nn
The RPG statement starts in 9
ELSE IF characters 1-7 contain xxxxxxn
The RPG statement starts in 8
ELSE The RPG statement starts in 1
(Where each n is a digit and each x is a digit or blank.)
After finding the beginning position, RPG/free uses similar logic
to check the tail of the first statement to find the ending position. If no
SRCDAT or SRCSEQ field is found at the end of the first statement, the
statement ending is the end-of-line character.
If you have problems, just strip off any non-RPG line numbers. (Do NOT
strip off RPG statement numbers in positions 1-5; use the /nbr:ignore option
to ignore them.)
VIII.B. TAB CONVERSION:
RPG/pretty does not normally convert tabs to blanks on input. If you
use Lattice "compressed" source (the Lattice default), you should use the
/cvttab to force RPG/pretty to convert tabs to blanks.
VIII.C. PROGRAM ID:
If you specify /ignpid, RPG/pretty cuts out the program ID (positions
75-80) for all input lines except: input following the data sentinel (e.g.,
**) and non-commented H-specs. Any non-blank input beyond position 80 is
concatenated to the statement up to position 74.
VIII.D. COMMENTS:
Comment lines that are not C-specs are output as the formtype followed
by an asterisk (with /noform, just an asterisk). For example,
F* comment...
You may want to use a PC editor to search and replace this pattern
(e.g., F*) with -- which is the standard RPG/free comment. The current
RPG/pretty approach maintains better alignment for commented non-C-specs in
existing code.
C-spec comments beginning in position 60 are output as a trailing
comment (using --) following the operation when you use /cmtline:same. With
/cmtline:prv, comments are output on a separate line before the operation
and are indented to line-up with the operation.
The cmtline:xxx option applies only to comments in positions 60 or
higher of a C-spec. Standalone comments (e.g., F* Comment ... ) are always
output on the same line.
VIII.E. MISCELLANEOUS:
Some invalid specifications do not cause a warning; for example, an
indicator like UX is considered valid. RPG/free will catch many of these.
All opcode lookups are done in UPPERCASE (as standard RPG requires).
IX. REVERSE TRANSLATION
------------------------
Version 2.0 will reverse translate many basic RPG and RPG/free programs.
However, several powerful features of RPG/free cannot be reverse translated.
If you must maintain a standard RPG version of a program so that it can be
edited, the following guidelines will help you. I would recommend you avoid
editing the standard RPG code, if possible, because that will let you take
advantage of all of RPG/free's productivity enhancements.
To repeatedly cycle a program through RPG/pretty and RPG/free, You
must use /cmtline:same option with both RPG/free and RPG/pretty to
get reversible comment format. Do NOT use the RPG/pretty /nodir, or /trimcmt
options.
Use the following RPG/pretty switches, as needed:
/cvttab If your standard RPG includes tab characters
/ignmsglines If your input contains embedded compiler messages
/ignpid If you have the program ID in positions 75-80
/nbr:nonblank If you have data in positions 1-5 of source
Use the following RPG/free switche, as needed:
/pgmid:xxx If your standard RPG program has a program ID
Use the standard comment style (e.g., F* Comment... ) for comments
that are not within the C-specs.
RPG/free does not reverse translate code generated by
the following RPG/free features: macro definition and expansion (/DEFINE
etc.); conditional translation (/IF DEFINED, etc.); extended control
structures (LOOP, BREAK, CONTINUE, EXITBLOCK); extended assignment
operations (XMOVE, XCAT, XCATST, XSUBST); DCL free-standing declarations;
*TRUE and *FALSE special values;
RPG/free translates C-spec operands into RPG/free positional format, not
keyworded format (e.g., F1, FMT, etc.).
You may need to cycle your program once before it is in a format that
will reverse exactly. Both RPG/pretty and RPG/free make some minor shifts
to put things in a standard form for reverse translation.
X. IMPLEMENTATION NOTES
-----------------------
This version of RPG/pretty is implemented with PolyAWK compiler v. 1.1BETA.
This version of RPG/free is implemented with Microsoft QuickC v. 2.51.
Both programs were implemented on an IBM PS/2 Model 55SX with IBM PC-DOS 4.01.
X.A. MAXIMA:
RPG/free has the following maxima:
Input files 20 (or DOS limit)
File name length 90
Number of command line arguments 20
Command argument length 90
Number of continuation lines 19
Input line length 250
Output line length 250
Statement length 1000
Keyword length 20
Token length 80
Macro name length 30
Macro replacement text length 250
Number of macros 200
Nesting levels for conditional directives 20
Nesting levels for control structures 20
RPG/pretty has the following maxima:
Input files 1
File name length 90
Number of command line arguments 20
Command argument length 90
Input line length 250
Output line length 250
Statement length 1000
Nesting levels for control structures 20
XI. THE RPG/free LANGUAGE
-------------------------
An introduction to RPG/free is published in the article "RPG/free -- The
Golden Age of RPG Programming", Paul Conte, NEWS 3X/400, April 1990. Copies
of this article are available as a back issue order from NEWS 3X/400, P.O.
Box 3438, Loveland, CO 80539-9916 (800) 373-3853. The article covers
version 1.0.
XI.A. STATEMENTS
An RPG/free program consists of a file of "statements". Most RPG/free
statements can be continued across multiple input lines. Statements include:
Statement type Example
--------------------------- ------------------------------------
RPG/free directives /CALC, /DEFINE
Standard RPG directives /TITLE, /EXEC SQL
SQL statements SELECT * FROM CUST
Non-C-spec FCUST I E DISK
Commented non-C-spec *F Comment
C-spec assignment x = y
C-spec keyword operation READ cust EOF( eof_cust )
RPG/free comment line -- Comment
Blank line
Data Abcdef...
XI.B. COMMENTS
You can add a trailing comment to any RPG/free statement, except the
/EXEC SQL and /TITLE directives and SQL statements between /EXEC SQL and
/END-EXEC. Comments can be added to other directives and non-C-specs, as
well as C-specs. You cannot add comments to lines that follow the /DATA
directive, lines between /FIX and /FREE directives, or lines in a file
included with the /INCLUDEF directive. (You can place comments on lines in
a file included with the /INCLUDE directive.)
Use two adjacent dashes (--) to begin a comment. For example:
add a b -- This is a comment
The comment ends at the end of the input line or at the last character
before a plus sign (+) indicates a continued statement. The first
unquoted -- in a line marks the beginning of the comment. Although you can
generally leave blanks out of assignment operations (e.g., a=b-c), don't code
"b minus -3" as b--3 because the --3 will be treated as a comment.
You cannot place comments (or any --) WITHIN the replacement text of a
macro because comments are stripped from the macro definition as the input
lines are read. You can have comments on the macro definition statement
itself, which is generally all you need for macro documentation.
To code a comment line, just begin with -- anywhere in the line.
XI.C. CONTINUATION:
You can continue any RPG/free statement, except the /EXEC SQL and /TITLE
directives and SQL statements between /EXEC SQL and /END-EXEC. You can
continue other directives and non-C-specs, as well as C-specs. You cannot
continue lines that follow the /DATA directive, lines between /FIX and /FREE
directives, or lines in a file included with the /INCLUDEF directive. (You
can continue lines in a file included with the /INCLUDE directive.)
To continue a statement, use a plus (+) as the last nonblank, nontab
character on a line. For example:
XMOVE 'Name' +
outfld
When the RPG/free precompiler reads an input line that can be
continued (i.e., it is not in an /INCLUDEF file, not between /FIX and
/FREE directives, not an /EXEC SQL or /TITLE directive, and not a SQL
statement between /EXEC SQL and /END-EXEC), the precompiler first checks
for, and removes, a trailing + specifying a continued statement. The
precompiler than scans the line for an unquoted -- marking the beginning of a
comment. Any comment is removed from the input line and saved until
the entire statement has been built.
The precompiler reads the next line and removes all leading blanks
before the line is concatenated to the end of the continued line. The
precompiler repeats this process until the end of a statement (i.e., no
continuation or end-of-input).
If you specified /cmtline:same, the comments are concatenated into one
long comment and output at the end of the statement (the exact position
depends on the statement type). If you specified /cmtline:prv, the
comments are output one line per comment before the statement is translated.
After building the statement and handling comments, the precompiler
parses the input statement according to RPG/free syntax rules.
If you need to end a line with + (e.g., in the replacement text of a
macro), just code it like:
/DEFINE bump 1 + --Comment to allow + as last character
The trailing comment will be stripped, and the line will end with +.
XI.D. PROGRAM STRUCTURE:
RPG/free programs have the same structure as standard RPG programs. You
specify the form type with a directive. A complete program might contain:
/AUTORPT
Auto-report specifications
/CONTROL or /HEADER (optional)
Control specifications
/FILE
File specifications
/EXTENSION or /EXT
Extension specifications
/LINE
Line counter specifications
/TELCOM
Telecommunications specifications
/INPUT
Input specifications
/CALC
Calculation specifications
/OUTPUT
Output specifications
/DATA
**
File translation records
**
Alternate collating sequence records
**
Compile-time array and table data
The precompiler starts with form type as H, so a beginning /CONTROL is
optional. You do not have to include directives for unused form types.
The form types must be in the standard RPG order, the precompiler does not
sort them.
XI.E. NON-C-SPEC STATEMENTS:
H, F, E, L, T, I, O, and U specifications are output without
translation, except for proper column alignment based on the /FIRSTCOL
directive setting.
With the default /FIRSTCOL setting (6), you begin each statement with
the form character in position 1. (This is redundant, but aids readability.)
To eliminate form characters, use the /FIRSTCOL 7 directive.
To add characters in positions 1-5, use /FIRSTCOL n where n is 1 to 5
and specifies where position 1 of the input will be placed in the output.
You can use multiple /FIRSTCOL directives, so you can bracket a statement
that you want to mark and leave the others as the default:
FAFILE1 ....
/FIRSTCOL 4
>>FAFILE2 ...
/FIRSTCOL 6
FAFILE3 ...
Non-C-specs are not translated to uppercase, so you must code uppercase
where the RPG compiler requires it.
XI.F. C-SPEC STATEMENTS:
C-specs are free format, you can use blanks and tabs freely for
alignment. You can also use upper or lower case for all keywords,
identifiers, and special values. Lower case is converted to upper case
except within the sequence field (e.g., {v1.0} is unchanged), string
constants (e.g., 'Name' is unchanged), and figurative constants
(e.g., *all'x' becomes *ALL'x').
A complete C-spec has the following parts:
Sequence field
Control level indicator
Conditioning indicators
Operation
Declaration
Half-adjust
Resulting indicators
Rules for combining these parts are the same as in standard RPG.
XI.G. MULTIPLE C-SPEC STATEMENTS:
You can code multiple RPG/free C-specs on a single statement by
separating the C-specs with a semicolon (;). For example:
tmp = a; a = b; b = tmp -- Swap a and b
Statements with multiple C-specs can be continued across input lines,
which is valuable primarily for defining macros that have multiple C-specs.
For example:
/DEFINE chksql +
if sqlcod <> 0; +
exsr sqlerr; +
endif
can be used to simplify checking SQL return codes, as follows:
/EXEC SQL
SELECT * FROM cust WHERE custid = :inpid
/END-EXEC
chksql
You cannot code directives or any other non-C-spec statement on a
multiple-C-spec statement.
XI.H. SEQUENCE FIELD (1-5):
You can specify up to five characters to output in the standard RPG
sequence field. Use curly braces to delimit the sequence field:
{V3.2a} will generate: V3.2a in positions 1-5.
Here are a couple more examples:
{12345} a = b
{ >>} READE custr
You cannot use a right brace (}), a single quote ('), or double dashes
(--) within the sequence field. The sequence field is truncated to five
characters. Within the braces, all blanks are significant. The
sequence field can be continued across lines with a +, but that is not good
programming practice.
XI.I. CONTROL LEVEL INDICATOR (7-8):
You can specify a control level indictor in two ways. You can use any
one of the following control level indicator keywords:
L0() L1() L2() L3() L4()
L5() L6() L7() L8() L9() LR()
You must use the parentheses. The left parenthesis must immediately
follow the keyword. You can use blanks or tabs anywhere within the
parentheses.
Alternately, you can use a form like LEVEL(L0) to specify L0-L9 or LR.
The indicator can be a standard level indicator (L0, ..., LR) or a symbolic
indicator (*INL0, ..., *INLR).
XI.J. CONDITIONING INDICATORS (7-8 and 9-17):
You can specify up to three conditioning indicators for each statement
as:
(01 02 03) or First or only conditioning indicators
COND(01 02 03) for statement
AND(01 02 03) AND'd indicators, puts AN in 7-8
OR(01 02 03) OR'd indicators, puts OR in 7-8
You can specify negated indicators as (n01 n02 n03).
You can use symbolic indicators as (*in01 *in02 *in03) or
(*inn01 *inn02 *inn03).
XI.K. OPERATION (18-48):
The operation specifies what will be generated for the standard RPG
opcode (positions 28-32), Factor1 (18-27), Factor2 (33-42), and
Result (43-48).
Allowable operands for Factor1, Factor2, and Result are:
Operand type Example Fact1 Fact2 Result
------------------------------ ------- ----- ----- ------
Identifier custid Y Y Y
Subscripted identifier ary,2 Y Y Y
Non-negated symbolic indicator *IN01 Y Y Y
Subscripted indicator array *IN,i Y Y Y
Null placeholder *N Y Y Y
Special value *zero Y Y Y
Numeric constant -1.2 Y Y N
String constant 'Name' Y Y N
String reference str:strlen Y Y N
Figurative constant *all'X' Y Y N
Hexadecimal constant x'f0' Y Y N
Within operations, array references have the same form as in
standard RPG, except you can use blanks around the comma. For example:
ADD X, I Y, I or
ADD X , I Y , I
Release 3.0 of RPG/400 allows string references that have two parts
seperated by a colon. In RPG/free, you can use blanks around the colon. For
example:
SUBSTR LEN( strlen ) SRCSTR( old_str : bgnpos ) TGTSTR( new_str )
XI.L. RPG/free OPERATIONS:
There are two forms of RPG/free operation: arithmetic assignment and
keyword operation.
XI.M. ARITHMETIC ASSIGNMENTS:
Arithmetic assignments have the form: a = b or a = b + c
You can use a single +, *, -, or / arithmetic operator.
You can't use parentheses or compound expressions such as
a = (b + c) * d.
XI.N. KEYWORD OPERATIONS:
Standard keyword operations have an operation-operand form:
operation factor1 factor2 result
If an operation has blank or optional Factor1 or Factor2, you usually do
not have to specify it. RPG/free looks up the operation and places operands
where they belong. You can use the placeholder *n or *N to explicitly
place blanks in an operand field. For example,
DELETE cusrcd generates DELETCUSRCD
DELETE *n cusrcd generates DELETCUSRCD
DELETE custid cusrcd generates CUSTID DELETCUSRCD
UPDATE cusfil generates UPDATCUSFIL
UPDATE cusfil cusds generates UPDATCUSFIL CUSDS
Note that RPG II and RPG III have different rules for the following
opcodes: CHAIN, DEBUG, DEFN, POST, READ, READE, and READP. RPG/free default
placement will correctly handle all versions of CHAIN, READ, READE, and
READP. You can use either the /rpgii option or explicit *n placeholders for
the RPG II versions of DEBUG, DEFN, and POST.
RPG/400 (R3.0 and later) differs from RPG III in letting Factor1 be
optional on READE and REDPE. You can use either the /rpg400 option or
explicitly code *n placeholders when you don't use Factor1.
XI.O. OPCODE SYNONYMS:
You can use the following correctly spelled synonyms instead of standard
RPG opcodes:
RPG/free synonym Standard RPG opcode
---------------- -------------------
BITOFF BITOF
CATSTR CAT (RPG/400)
CATST (Lattice)
CASE CAS
COMMIT COMIT
DELETE DELET
DISPLAY DSPLY
ENDCASE END
ENDDO END
ENDFOR END
ENDIF END
ENDLOOP END
ENDSUBSTR (second part of a Lattice SUBST operation)
ENDUNTIL END
ENDWHILE END
EXITSR EXITBLOCK (RPG/free extended operation)
LOOKUP LOKUP
OCCUR OCUR
READPE REDPE
RETURN RETRN
ROLLBACK ROLBK
SETOFF SETOF
SUBSTR SUBST
UNLOCK UNLCK
UPDATE UPDAT
XCATSTR XCAT (RPG/free extended operation)
XSUBSTR XSUBST (RPG/free extended operation)
XI.P. OPERAND KEYWORDS:
If you think of C-spec operands as Factor1, Factor2, Result instead of
first, second, and third operands, you can use RPG/free operand keywords as
in the examples below. Operands can be in any order when you use keywords;
and you can use blanks freely within the parentheses.
UPDATE F2( cusfil ) R( cusds )
add f1( x ) f2( y ) r( z )
add r( z ) f2( y ) f1( x )
The following operations have synonyms for the F1, F2, and R keywords.
------------- Keyword ------------------
Opcode F1 F2 R
------ --------- ---------- --------
ACQ DEV FILE
BITOF SELECT DATA
BITON SELECT DATA
CABxx F1 F2 TAG
CAS F1 F2 SUBR
CASE F1 F2 SUBR
CASxx F1 F2 SUBR
CHAIN KEY FILE or FMT DS
CLEAR F1 DS
CLOSE FILE
DEBUG ID FILE DATA
DEFN TYPE REFFLD or FLD
DTAARA
DELET KEY FILE or FMT
DO FROM TO IDX
DSPLY MSG or MSGID TO REPLY
END INC
ENDSR TAG CONTROL
ENDSS STRLEN TGTSTR
EXFMT FMT
FEOD FILE
FOR FROM TO IDX
FORCE FILE
IN LOCK DTAARA
LOKUP ARG TABLE or MATCHTBL
ARRAY
NEXT DEV FILE
OCUR SETIDX DS RESULTIDX
OPEN FILE
OUT LOCK DTAARA
PARM RTNVAL INVAL FLD
POST DEV FILE DS
READ FILE or FMT DS
READC FMT
READE KEY FILE or FMT DS
READP FILE or FMT DS
REDPE KEY FILE or FMT DS
REL DEV FILE R
RESET F1 DS
SCAN COMP BASE POS
SETGT KEY FILE or FMT
SETLL KEY FILE or FMT
SUBST STRLEN SRCSTR TGTSTR -- RPG/400
SUBST SRCSTR BGNPOS -- Lattice
TESTB SELECT DATA
UNLCK DTAARA
UPDAT FILE or FMT DS
WRITE FILE or FMT DS
XSUBST STRLEN SRCSTR TGTSTR
These synonyms can make your code very readable. You can mix F1, F2,
and R with the synonyms, but you can only use the synonyms defined for each
opcode. For example, the following is valid:
SUBST R( x ) F2( y : bgn ) STRLEN( strlen )
but
SUBST R( x ) FILE( y : bgn ) STRLEN( strlen )
is not.
You can mix the keyword and positional forms, but be careful because the
default placement of operands does not work the same as in S/38 and OS/400
CL. RPG/free first places operands specified with keywords, then fills in
vacant operands using its default rules.
XI.Q. EXTENDED CONTROL STRUCTURE OPERATIONS:
RPG/free has a set of extended operations for control structures:
RPG/free Standard RPG
--------------------- ---------------------------------------
AND f1 = f2 F1 ANDEQF2
AND f1 F1 ANDEQ'1'
BREAK GOTO BRK#1#
CASE f1 < f2 r F1 CASLTF2 R
CASE f1 r F1 CASEQ'1' R
CASE r CAS R
CONTINUE GOTO CNT#1#
FOR r = f1 f2 F1 DO F2 R
ENDFOR f2 END F2
EXITBLOCK GOTO EXT#1#
EXITSR GOTO EXT#1#
IF f1 <= f2 F1 IFLE F2
IF f1 F1 IFEQ '1'
LOOP '1' DOWEQ'1'
OR f1 > f2 F1 ORGT F2
OR f1 F1 OREQ '1'
UNTIL f1 <> f2 F1 DOUNEF2
UNTIL f1 F1 DOUEQ'1'
WHILE f1 >= f2 F1 DOWGEF2
WHILE f1 F1 DOWEQ'1'
The logical operators are:
Operator Meaning
-------- --------------
< Less than
<= Less than or equal
= Equal
<> Not equal
>= Greater than or equal
> Greater than
You can also use operand keywords with extended operations (although it
isn't very readable):
IF f1(x) op(<=) f2(y)
FOR r(idx) op(=) f1(bgn) f2(end)
The "noise" word TO is defined as a macro with blank replacement text,
so you can code:
FOR i = 1 TO n
for readability.
There are four built-in macros that you can use with control
structures:
Macro name Replacement text
---------- ----------------
*AND ;AND
*OR ;OR
*NOT IF *TRUE <>
ELSEIF ELSE; IF
The *AND and *OR operators let you use unparenthesized logical expressions:
IF a = b *AND c = d
Note that because *AND and *OR just generate a series of standard RPG
ANDxx and ORxx operations, you cannot use parenthesized logical expressions.
The *NOT operator can be used with "logical" variables:
IF *NOT end_of_file
You cannot use *NOT to negate a logical expression.
The ELSEIF macro lets you code "else if" logical constructs in a
slightly more compact and readable fashion:
IF a = b
....
ELSEIF a = c
....
ELSE; ....
ENDIF; ENDIF
Note that you must still code one ENDIF to match the IF, and one ENDIF
to match each ELSEIF.
The BREAK, CONTINUE, EXITBLOCK, and EXITSR labels are generated by
RPG/free to match TAG labels that are generated at the end of a loop, main
block, or subroutine.
You can code loops as follows:
/DEFINE eof_cust *IN90
LOOP
READ FMT( custr ) EOF( eof_cust )
IF eof_cust
BREAK
ENDIF
-- Process a customer
...
ENDLOOP
The LOOP operation is a never-ending loop; you should use BREAK or
EXITBLOCK to exit the loop.
The BREAK operation exits the innermost loop.
The CONTINUE operation skips the rest if the innermost loop
and immediately branches to the loop's test condition. Another iteration
will execute, if-and-only-if the loop condition is still true.
The EXITBLOCK operation exits the current subroutine, or the main block
that precedes the first subroutine.
XI.R. EXTENDED CHARACTER ASSIGNMENT OPERATIONS:
RPG/free provides "safe" assignment operations for character variables.
These operations blank fill the Result before executing the operation, so you
don't get garbage left in the result.
RPG/free Standard RPG
--------------------- ---------------------------------------
XCAT f1 f2 r MOVE *BLANK R
F1 CAT F2 R
XCATST f1 f2 r MOVE *BLANK R
F1 CATSTF2 R
XMOVE f2 r MOVE *BLANK R
MOVELF2 R
XSUBST f1 f2 r MOVE *BLANK R
F1 SUBSTF2 R
You should not use the extended string operations with the same
operand used for both the Result and either Factor1 or Factor2 because
blanks will be moved to the Factor1 or Factor2 before the string
operation. (RPG/free will emit a warning if you do.)
As an example, do NOT code:
XCAT r f2 r
Instead, if you want to append f2 to r, code:
CAT r f2:0 r
Note that you must code the number of blanks to be inserted (the :0)
or else you will simple move r to r. (RPG/400 provides no mechanism
to build real, variable length strings.)
XI.S. DECLARATIONS (49-52):
After an operation and its operands, you can declare the Result field:
ADD x y z LEN(7 0) Declares numeric field Z
a = b * c LEN(7 2) Declares numeric field A
MOVE 'Name' outfld LEN(8) Declares character field OUTFLD
You can use relative sizes on the DEFN operation:
DEFN *LIKE x z LEN(+2) Declares numeric field Z as 2
positions larger than X.
XI.T. DCL OPERATION:
The RPG/free DCL extended operation allows independent field
declarations.
RPG/free operation Standard RPG
------------------ ---------------------------
DCL r LEN(5) MOVELR R 5
DCL r LEN(5 0) Z-ADDR R 50
DCL f2 r LEN(5) MOVE *BLANK R 5
MOVELF2 R
DCL f2 r LEN(5 0) Z-ADDF2 r 50
Note that the DCL generates executable statements. You may want to put
these in an initialization subroutine that is executed only once (in R3.0 of
RPG/400, you can use the *INZSR subroutine). Or, you can put DCL
statements under a conditional statement:
IF pgminz = *FALSE
DCL inpcid LEN(5 0)
...
MOVE *TRUE TO pgminz
ENDIF
XI.U. HALF-ADJUST (53):
On arithmetic operations, you can code H() to specify half-adjust.
XI.V. RESULTING INDICATORS (54-59):
You can specify up to three resulting indicators in two ways: as a list
enclosed within RESULT(...) or with individual resulting indicator keywords.
The three relative positions within a RESULT(...) list correspond to
positions 54-55, 56-57, and 58-59. For example:
555555
RPG/free 456789
---------------- ------
RESULT(01 *n 02) generates 01 02
You can use symbolic indicators, as in RESULT(*in01 *in02). You cannot
use negated indicators (e.g., N01).
Instead of a RESULT(...) list, you can use the following keywords:
54-55 56-57 58-59 Notes
---------- ---------- ---------- -----------
RI1 RI2 RI3 e.g., SETON
POS NEG ZER e.g., ADD
ZERO
ZERBLK e.g., MOVE
BLANK
BLK
HI LO EQ e.g., LOKUP
NR ER EOF e.g., CHAIN, READ
ERR BOF e.g., READP
OFF MIX ON TESTB
ALLNUM LEADBLK ALLBLK TESTN
ZONEA ZONEJ ZONEX TESTZ
SHTDN SHTDN
FOUND SCAN
FND SCAN
You don't have to use the matching keywords for each operation.
For example, you can use:
MOVE x y HI(01) LO(02) EQ(03)
You can place resulting indicator keywords in any order, but you cannot
specify the same standard RPG positions more than once. You can use symbolic
indicators, but not negated indicators. You cannot use *n with resulting
indicator keywords other than RESULT.
XII. STANDARD RPG DIRECTIVES
----------------------------
RPG/free supports the following standard RPG compiler directives:
/COPY host-file-member-spec
/EJECT
/EXEC SQL sql-statement
sql-statement
...
/END-EXEC
/PRINT GEN
/PRINT NOGEN
/SKIP n
/SPACE n
/TITLE title
You can use blanks and tabs between a directive keyword and its
argument, the precompiler realigns the argument to meet standard RPG
requirements.
SQL statements between the /EXEC SQL and /END-EXEC directives must not
have the leading + used in standard RPG/400; the + is added by the
precompiler.
XIII. RPG/free DIRECTIVES
-------------------------
RPG/free includes the following precompiler directives:
/DEFINE identifier replacement-text Define a macro
/UNDEFINE identifier Remove macro definition
/DUMPMAC Output macro table to
file dump.rpf
/FIRSTCOL n Set output position
for non-C-specs
/FIX Begin fixed-format input
/FREE Resume free-format input
/IF DEFINED( macro ) Conditionally translate
/IF NOT DEFINED( macro ) statements
/ELSEIF DEFINED( macro )
/ELSEIF NOT DEFINED( macro )
/ELSE
/ENDIF
/INCLUDE pc-file-spec Include free-format
file
/INCLUDEF pc-file-spec Include fixed-format
file
XIII.A. SETTING FIRST COLUMN (/FIRSTCOL):
The /FIRSTCOL directive has an argument from 1 to 7 that specifies the
position in the standard RPG output where the first position in a non-C-spec
input line will be placed. The default is 6 which requires you to begin
non-C-specs with the proper form type character.
/FIRSTCOL does not effect lines between /FIX and /FREE directives, within
an /INCLUDEF file, or following the /DATA directive.
XIII.B. SOURCE MACROS (/DEFINE, /UNDEFINE, and /DUMPMAC):
An RPG/free source macro is an identifier for a string of
replacement text. Source macros are only supported for C-specs, the
precompiler will not translate macros in other types of statements.
Although RPG/free macros are fairly simple, they provide great
flexibility in creating highly readable programs. To define a macro, code
/DEFINE followed by one or more blanks and tabs and the macro name. Follow
the macro name with one or more blanks or tabs and then code the replacement
text. The replacement text begins with the first nonblank, nontab after the
macro name and ends with the last nonblank, nontab character on the same
statement.
The macro name must begin with a letter, national character ($, #, @),
or the underscore (_) readability character; and can include letters,
national characters, numbers, and underscore. Upper and lower case letters
are considered identical in matching macro names. A macro name can be up to
30 characters long.
The replacement text can include any characters, except leading or
trailing blanks and tabs, which are always trimmed; and double dashes (--),
which begin a comment. If you want to end a macro's replacement text with a
plus (+), code a comment after the + so it will not be handled as a
continuation. For example:
/DEFINE bump 1 + --Comment to allow + as last character
As the precompiler encounters tokens during its parse of an RPG/free
C-spec, it replaces every occurrence of a macro identifier with the
corresponding replacement text. The precompiler then restarts its parse at
the beginning of the replacement text, thus allowing nested macros. For
example:
/DEFINE customer_id csid
/DEFINE exit_key *in03
/DEFINE IFNOT IF *TRUE <>
IFNOT exit_key becomes IF '1' <> *in03
The precompiler does not replace a macro in any input line until after
it encounters the macro's definition on a /DEFINE.
If you code a /DEFINE with a macro name and replacement text that
is nothing but blanks and tabs, the precompiler replaces the macro name with
the null string (i.e., deletes it) when the macro is encountered in
subsequent input lines. The RPG/free precompiler automatically defines TO as
blanks when it starts (you can /UNDEFINE TO, if you don't want it replaced
with blank). You can use blank "noise" word macros to add readability words
to your statements:
/DEFINE FROM
ADD x TO y becomes ADD x y
SUB x FROM y becomes SUB x y
Be careful not to code recursive macros, which will cause a syntax
error:
/DEFINE x y
/DEFINE y x
a = x causes syntax error
To remove a macro definition, use /UNDEFINE with the macro name:
/DEFINE x csid
a = x becomes a = csid
/UNDEFINE x
a = x remains a = x
If you try to /DEFINE a macro that is already defined, you get an
error. (This prevents accidental redefinitions.) To redefine a macro,
you must first use /UNDEFINE to remove it from the definitions, and then
use /DEFINE for the new definition. You can use /IF DEFINED(macro),
discussed below, to conditionally define (or redefine) macros. For example:
/DEFINE customer_id csid
MOVE customer_id outfld becomes MOVE csid outfld
/UNDEFINE customer_id
/DEFINE customer_id custid
MOVE customer_id outfld becomes MOVE custid outfld
To prevent accidentally defining two macros as the same standard RPG
field, you can use the built-in macro function %SYSSYMBOL. For example,
if you coded the following:
/DEFINE cust_id CID
...
/DEFINE charge_ID CID
the generated RPG program might not work correctly because CID is used for
two different purposes. To prevent duplicate use of the same symbol as
replacement text, code:
/DEFINE cust_id %SYSSYMBOL( CID )
This definition checks all existing macros to be sure none uses CID as
the replacement text. All subsequent macros, whether they use %SYSSYMBOL
or not, are prevented from using CID as the replacement text. The
argument to %SYSSYMBOL is a single string with no embedded blanks, tabs,
or parantheses. You must use %SYSSYMBOL by itself, not as part of a
longer replacement string. (You can use nested macros, if you want to
use the symbol in a longer string.)
You can let RPG/free generate standard RPG names, if you don't need
to work directly with the generated RPG code:
/DEFINE cust_id %SYSSYMBOL( *GEN )
This is equivalent to a macro definition like:
/DEFINE cust_id %SYSSYMBOL( SYS#1# )
Each time *GEN is referenced, the RPG/free precompiler generates a new
six-character name similar to SYS#n# (or SYSnn#, SYnnn#, Snnnn#). Then
%SYSSYMBOL makes sure this name is not used as replacement text in any
other macro. %SYSSYMBOL( *GEN ) can greatly simplify using long
variable names in RPG/free.
You can achieve the effect of limiting the scope of macro names to
a single source file (i.e., a file that you /INCLUDE) by the defining
the macros at the beginning of the source file, using %SYSSYMBOL, and
undefining them at the end of the source file:
-- Beginning of myfile.rpi
/DEFINE local_var %SYSSYMBOL( *GEN )
.... code
/UNDEFINE local_var
-- end of myfile.rpi
With this technique, local_var can be used in several source files
without conflicts. The %SYSSYMBOL( *GEN ) uses a different RPG
field name for each source file, so there is no accidental conflicting
use of the same RPG variable. The /UNDEFINE lets the macro name
local_var be /DEFINE'd in multiple places.
The /DUMPMAC directive will write the table of current macro definitions
to the file dump.rpf. A header line provides the input line number when
the table was dumped. Each macro is output as:
[macroname] [replacement text] [x]
where x is 'S' if the macro is defined as a %SYSSYMBOL, and blank otherwise.
You can use /DUMPMAC to trace macro definitions if you are having problems
in your program. When RPG/free encounters the first /DUMPMAC directive,
it clears dump.rpf before writing out the table. When it encounters
subsequent /DUMPMAC directives, it appends the current table to the file.
XIII.C. PREDEFINED LANGUAGE, COMPILER, and LOGICAL CONSTANT MACROS
When RPG/free starts, it defines macros for the version of RPG/free and
the target RPG language and compiler that were specified (or defaulted) for
the translation. You can test these with /IF DEFINED (see below) to direct
the translation based on RPG/free version or the target compiler.
The PC version of RPG/free defines the following macros:
Macros defined Replacement text
-------------------- -----------------------
_RPGFREE_VER_PC_ 'PC2.02'
_RPGFREE_VER_SYS_ 'PC'
_RPGFREE_VER_NBR_ 2.02
You can test _RPGFREE_VER_PC_ (and the other macros defined by the
other versions of RPG/free) to handle the proper file specification
syntax on /INCLUDE directives:
/IF DEFINED( _RPGFREE_VER_PC_ )
/INCLUDE stdhdr.rpi
/ELSEIF DEFINED( _RPGFREE_VER_AS400_ )
/INCLUDE rpisrc(stdhdr)
/ENDIF
You can also use these three macros in RPG/free C-specs to
either conditionally control execution (not precompilation) or to
display the version of the precompiler used. For example:
/DEFINE output_field OUTFLD
XMOVE _RPGFREE_VER_PC TO output_field
will generate:
MOVE *BLANK OUTFLD
MOVEL'PC2.02' OUTFLD
The compiler options define the following macros:
Option Macros defined Replacement text
-------------- -------------------- -----------------------
/asna _ASNA_ ASNA
_RPG400_ RPG400
/bps _BPS_ BPS
_RPGII_ RPGII
/cspi _CSPI_ CSPI
_RPGII_ RPGII
/cspi400 _CSPI400_ CSPI400
_RPG400_ RPG400
/lattice _LATTICE_ LATTICE
_RPGII_ RPGII
/native _NATIVE_ NATIVE
_RPG400_ RPG400
/rpgii _IBMII_ IBMII
_RPGII_ RPGII
/rpgiii _IBMIII_ IBMIII
_RPGIII_ RPGIII
/rpg400 _IBM400_ IBM400
_RPG400_ RPG400
/softwest _SOFTWEST_ SOFTWEST
_RPGII_ RPGII
/trident _TRIDENT_ TRIDENT
_RPGIII_ RPGIII
You can use /IF DEFINED(...) to control precompilation based on the
target language. For example:
/IF DEFINED( _IBM400_ )
XCATSTR a b c
/ELSE
CALL 'CATSTR'
PARM a
PARM alen
PARM b
PARM blen
PARM c
PARM clen
/ENDIF
This facility lets you maintain a single source code file for multiple
target compilers.
RPG/free also installs the following macros based on the target RPG
compiler:
_RPGFREE_LANGUAGE_ as 'RPGII', 'RPGIII', or 'RPG400'
_RPGFREE_COMPILER_ as 'ASNA', 'BPS', 'CSPI', etc.
You can use _RPGFREE_LANGUAGE_ and _RPGFREE_COMPILER_ macros in RPG/free
C-specs, if you want to test or output the target language or compiler.
RPG/free also automatically defines the macros:
*TRUE '1'
*FALSE '0'
*AND ;AND
*OR ;OR
*NOT IF *TRUE <>
ELSEIF ELSE; IF
TO <blank>
You cannot /UNDEFINE or redefine *TRUE, *FALSE, *AND, *OR, and *NOT;
they have been established as the RPG/free standard for logical (Boolean)
values. You can use these in C-specs, as in the following example:
/DEFINE LGL LEN( 1 )
/DEFINE valid_order vldord
DCL valid_order LGL
MOVE *TRUE TO valid_order
XIII.D. DOS COMMAND LINE MACRO DEFINITION (/DEFINE:XXX OPTION)
You can also use the /define:xxx option to define one macro from the
DOS command line. For example, you can enter:
rf /define:test inp.rpf out.rpg
and the macro TEST will be defined with replacement text @TEST. You can then
use /IF DEFINED(TEST) to conditionally translate statements in the input
file. This allows you to control code generation without modifying the
source.
XIII.E. CONDITIONAL CODE GENERATION (/IF, /ELSEIF, /ELSE, and /ENDIF):
A set of conditional directives lets you test whether or not a macro
is defined, and either translate a group of statements, or throw them into
the "bit bucket".
The /IF and /ELSEIF directives must have a condition like:
/IF DEFINED( chksql )
/IF NOT DEFINED( chksql )
/ELSEIF DEFINED( chksql )
The only condition you can test is whether or not a macro is defined.
The DEFINED condition is true if-and-only-if the macro is currently defined.
It doesn't matter what the replacement text is; even a macro with null
replacement text is considered defined.
If an /IF condition is true, the statements between the /IF and
it's matching /ELSEIF, /ELSE, or /ENDIF are translated; otherwise these
statements are skipped.
The statements between an /ELSE and it's matching /ENDIF are translated
if no previous matching /IF or /ELSEIF condition was true.
An /ELSEIF condition is treated as an /IF, if no previous matching /IF
or /ELSEIF condition was true; otherwise, it's treated as an /ELSE.
The normal rules of conditional statements apply to combining and
nesting /IF, /ELSEIF, /ELSE, and, /ENDIF.
Conditional directives control translation of all statement types,
including non-C-specs, data, and directives such as /DEFINE, /FIX, /FIRSTCOL,
/INCLUDE, and /INCLUDEF, and /EXEC SQL.
You can use /IF to make sure you don't try to redefine commonly used
macros. The following example shows how you could define a small set of
macros for common data types:
/IF NOT DEFINED( _TYPE_MACS )
/DEFINE _TYPE_MACS
/DEFINE LGL LEN( 1 )
/DEFINE INT LEN( 7 0 )
/DEFINE DOLLAR LEN( 9 2 )
/ENDIF
If these statements are put in an /INCLUDE file (see below), you can
safely /INCLUDE the file in multiple places without worrying about an illegal
duplicate definition of the type macros. I recommend you follow the
convention of beginning each "flag" macro, such as _TYPE_MACS in this
example, with an underscore. Using a standard notation for "flag" macro
names helps avoid collisions with regular macro names.
You can use conditional directives anywhere except between /FIX and
/FREE directives or within an /INCLUDEF file (the precompiler will not "see"
any other directives between /FIX and /FREE or within an /INCLUDEF file).
You can use conditional directives within a /INCLUDE file (in fact, that's
one of the most common places you'll use them).
You can also use conditional directives following a /DATA directive.
The /IF and other directives will not be output in the data, so you have a
convenient way to conditionally generate array and table contents, as well as
executable code.
XIII.F. FIXED FORMAT INPUT (/FIX and /FREE):
You can included standard, fixed-format RPG in an RPG/free source file
by placing it after a /FIX directive. All records following a /FIX directive
are moved without any modification to the output. Fixed format lines end
when a /FREE directive or end-of-file is encountered. If end-of-file is
encountered while a /FIX is in effect, RPG/free will generate a commented
/FREE to mark the end of the fix-format output. You cannot span multiple
input files with a /FIX; you must code a /FIX at the beginning of each one.
(This approach prevents "runaway" /FIX directives.)
XIII.G. INCLUDING SOURCE FILES (/INCLUDE and /INCLUDEF):
You can include RPG/free source at any point in the input by coding an
/INCLUDE directive with a PC file specification:
/INCLUDE include1.rpf
You can nest /INCLUDEs up to 20 deep (or the current DOS limit on open
files), but you cannot use recursive /INCLUDEs.
With /INCLUDE, all input is treated as RPG/free code (unless the
included file contains a /FIX or /DATA directive).
To include standard, fixed-format RPG, use /INCLUDEF. All input lines
from a file specified on an /INCLUDEF are treated the same as if they
followed a /FIX directive. The RPG/free precompiler does not recognize any
directives within a file included using /INCLUDEF.
RPG/free will generate a commented /ENDINCLUDE or /ENDINCLUDEF at the
end of included statements, unless the /ENDINCLUDE or /ENDINCLUDEF would
occur in data (i.e., following a /DATA directive).
XIII.H. COMBINING MACROS AND INCLUDE FILES:
A powerful technique is to use /INCLUDEs to "reuse" standard macros.
Consider the following file as typmac.rpm:
/IF NOT DEFINED( _TYPE_MACS )
/DEFINE _TYPE_MACS
/DEFINE LGL LEN( 1 )
/DEFINE INT LEN( 7 0 )
/DEFINE DOLLAR LEN( 9 2 )
/ENDIF
Then in any RPG/free program, you can simply code:
/INCLUDE typmac.rpm
to get the standard type definitions. You can create /INCLUDE files for
indicator definitions, standard variable declarations, etc.
Another technique is to define standard long names for database file
fields. Consider the following file as custffd.rpm:
-- Customer (CUSMST) file field descriptions
/IF NOT DEFINED( _Cust_FFD_Dfn )
/DEFINE _Cust_FFD_Dfn
/DEFINE Cust_ID csid
/DEFINE Cust_name csnam
/DEFINE Cust_discount csdsc
...
/ENDIF
In any program that references the CUSMST file, you can simply code:
/INCLUDE custffd.rpm
to make available the standard long names. On the S/38 and AS/400, you can
automatically generate files like custffd.rpm by using the DSPFFD (Display
File Field Description) command. The command CRTRPFFD (Create RPG/free
Field Descriptions) automates this process, and is available for downloading
from the NEWSLINK BBS.
XIV. THE FUTURE OF RPG/free
---------------------------
I'm working on the following features for RPG/free:
* Full arithmetic expressions: a = ( b + c ) * d
* Full logical expressions: IF ( a <> b ) & ( ( c = d ) | ( c = e ) )
* String expressions: s = r || t
* Free-format H-, ..., O-specs using OS/400 CL style syntax.
* Substitution parameters in macro definitions.
* Built in string and evaluation functions in macros and conditional
directives.
* Faster translation algorithms and dynamic storage management for
better performance.
If you have suggestions, please let me know.
Good luck to all "/free spirit" programmers!!!
-- End of RFREE.DOC --
----------------------